home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 October: Mac OS SDK / Dev.CD Oct 96 SDK / Dev.CD Oct 96 SDK2.toast / Development Kits (Disc 2) / OpenDoc Development Framework / ODFDev / ODF / OS / FWODMisc / Sources / FWFxMath.cpp < prev    next >
Encoding:
Text File  |  1996-08-16  |  8.0 KB  |  314 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                FWFxMath.cpp
  4. //    Release Version:    $ ODF 1 $
  5. //
  6. //    Copyright:            (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  7. //
  8. //========================================================================================
  9.  
  10. #include "FWOS.hpp"
  11.  
  12. #ifndef FWFXMATH_H
  13. #include "FWFxMath.h"
  14. #endif
  15.  
  16. #ifndef FWSTREAM_H
  17. #include "FWStream.h"
  18. #endif
  19.  
  20. #ifdef FW_DEBUG
  21. #include <stdio.h>
  22. #endif
  23.  
  24. #ifdef FW_BUILD_MAC
  25. #pragma segment fwodmisc_fixedmath
  26. #endif
  27.  
  28. //========================================================================================
  29. // FW_Fixed
  30. //========================================================================================
  31.  
  32. //----------------------------------------------------------------------------------------
  33. //    FW_Sin
  34. //----------------------------------------------------------------------------------------
  35.  
  36. FW_Fixed FW_Sin(FW_Fixed f)
  37. {
  38.     ODFract fract = ODFractSinCos(f.fRep, NULL);
  39.     return FW_ODFixedToFixed(fract >> 14);
  40. }
  41.  
  42. //----------------------------------------------------------------------------------------
  43. //    FW_Cos
  44. //----------------------------------------------------------------------------------------
  45.  
  46. FW_Fixed FW_Cos(FW_Fixed f)
  47. {
  48.     ODFract frac;
  49.     ODFractSinCos(f.fRep, &frac);
  50.     return FW_ODFixedToFixed(frac >> 14);
  51. }
  52.  
  53. //----------------------------------------------------------------------------------------
  54. //    FW_Sqrt
  55. //----------------------------------------------------------------------------------------
  56.  
  57. FW_Fixed FW_Sqrt(FW_Fixed f)
  58. {
  59.     ODWide wide;
  60.     wide.hi = 0;
  61.     wide.lo = f.fRep;
  62.     ODWideShift(&wide, -16);
  63.     
  64.     ODFixed fixed = ODWideSquareRoot(&wide);
  65.     return FW_ODFixedToFixed(fixed);
  66. }
  67.  
  68. //========================================================================================
  69. // FW_Wide
  70. //========================================================================================
  71.  
  72. //----------------------------------------------------------------------------------------
  73. //    FW_IntToWide
  74. //----------------------------------------------------------------------------------------
  75.  
  76. FW_Wide FW_IntToWide(int i)
  77. {
  78.     ODWide w = { i, 0 };
  79.     return FW_ODWideToWide(w);
  80. }
  81.  
  82. //----------------------------------------------------------------------------------------
  83. //    FW_FixedToWide
  84. //----------------------------------------------------------------------------------------
  85.  
  86. FW_Wide FW_FixedToWide(FW_Fixed f)
  87. {
  88.     ODWide w = { 0, f.fRep };
  89.     ODWideShift(&w, -16);
  90.     return FW_ODWideToWide(w);
  91. }
  92.  
  93. //----------------------------------------------------------------------------------------
  94. //    FW_ODFixedToWide
  95. //----------------------------------------------------------------------------------------
  96.  
  97. FW_Wide FW_ODFixedToWide(ODFixed f)
  98. {
  99.     ODWide w = { 0, f };
  100.     ODWideShift(&w, -16);
  101.     return FW_ODWideToWide(w);
  102. }
  103.  
  104. //----------------------------------------------------------------------------------------
  105. //    FW_WideToInt
  106. //----------------------------------------------------------------------------------------
  107.  
  108. int    FW_WideToInt(const FW_Wide& w1)
  109. {
  110.     ODWide w = w1.fRep;
  111.     ODWide h = { 0, 0x80000000l };
  112.     ODWideAdd(&w, &h);
  113.     return w.hi;
  114. }
  115.  
  116. //----------------------------------------------------------------------------------------
  117. //    FW_WideToODFixed
  118. //----------------------------------------------------------------------------------------
  119.  
  120. ODFixed    FW_WideToODFixed(const FW_Wide& w1)
  121. {
  122.     ODWide w = w1.fRep;
  123.     ODWide h = { 0, 0x00008000l };
  124.     ODWideAdd(&w, &h);
  125.  
  126.     const signed long  FW_kPrivMaxSignedWideToFixedInt = 0x00007FFF;
  127.     const signed long  FW_kPrivMinSignedWideToFixedInt = 0xFFFF8000;
  128.  
  129.     const ODFixed FW_kPrivMaxFixed = 0x7FFFFFFF;
  130.     const ODFixed FW_kPrivMinFixed = 0x80000000;
  131.     
  132.     if (w.hi > FW_kPrivMaxSignedWideToFixedInt)
  133.         return FW_kPrivMaxFixed;
  134.     
  135.     if (w.hi < FW_kPrivMinSignedWideToFixedInt)
  136.         return FW_kPrivMinFixed;
  137.         
  138.     return (w.hi << 16) | (w.lo >> 16);
  139. }
  140.  
  141. //----------------------------------------------------------------------------------------
  142. //    operator +
  143. //----------------------------------------------------------------------------------------
  144.  
  145. FW_Wide operator +    (const FW_Wide& w1, const FW_Wide& w2)
  146. {
  147.     ODWide w = w1.fRep;
  148.     ODWideAdd(&w, &w2.fRep);
  149.     return FW_ODWideToWide(w);
  150. }
  151.  
  152. //----------------------------------------------------------------------------------------
  153. //    operator -
  154. //----------------------------------------------------------------------------------------
  155.  
  156. FW_Wide operator -    (const FW_Wide& w1, const FW_Wide& w2)
  157. {
  158.     ODWide w = w1.fRep;
  159.     ODWideSubtract(&w, &w2.fRep);
  160.     return FW_ODWideToWide(w);
  161. }
  162.  
  163. //----------------------------------------------------------------------------------------
  164. //    FW_WideMultiply
  165. //----------------------------------------------------------------------------------------
  166.  
  167. FW_Wide FW_WideMultiply (FW_Fixed f1, FW_Fixed f2)
  168. {
  169.     ODWide w;
  170.     ODWideMultiply(f1.fRep, f2.fRep, &w);
  171.     return FW_ODWideToWide(w);
  172. }
  173.  
  174. //----------------------------------------------------------------------------------------
  175. //    operator /
  176. //----------------------------------------------------------------------------------------
  177.  
  178. FW_Fixed operator /    (const FW_Wide& w1, FW_Fixed f2)
  179. {
  180.     return FW_ODFixedToFixed(ODWideDivide(&w1.fRep, f2.fRep, NULL));
  181. }
  182.  
  183. //========================================================================================
  184. //    Global operators << and >>
  185. //========================================================================================
  186.  
  187. FW_CWritableStream& operator<<(FW_CWritableStream& stream, const FW_Fixed& fx)
  188. {
  189.     stream << fx.fRep;
  190.     return stream;
  191. }
  192.  
  193. FW_CReadableStream& operator>>(FW_CReadableStream& stream, FW_Fixed& fx)
  194. {
  195.     stream >> fx.fRep;
  196.     return stream;
  197. }
  198.  
  199. #ifdef FW_DEBUG
  200.  
  201. //========================================================================================
  202. //    Debug versions of math operators
  203. //========================================================================================
  204.  
  205. static void FixedError(FW_Fixed f1, FW_Fixed f2, const char* lpsz)
  206. {
  207.     char buf[250];
  208.     sprintf(buf, "Fixed error: %s, %.2f, %.2f", lpsz, FW_FixedToDouble(f1), FW_FixedToDouble(f2));
  209.     FW_DEBUG_MESSAGE(buf);
  210. }
  211.  
  212. FW_Fixed operator+(FW_Fixed f1, FW_Fixed f2)
  213. {
  214.     long rep1 = f1.fRep;
  215.     long rep2 = f2.fRep;
  216.  
  217.     long repr  = (rep1 >> 16) + (rep2 >> 16);
  218.  
  219.     if (repr < -32768 || repr > 32767)
  220.         FixedError(f1, f2, "Add oflw");
  221.  
  222.     return FW_ODFixedToFixed(f1.fRep + f2.fRep);
  223. }
  224.  
  225. FW_Fixed operator-(FW_Fixed f1, FW_Fixed f2)
  226. {
  227.     long rep1 = f1.fRep;
  228.     long rep2 = f2.fRep;
  229.  
  230.     long repr  = (rep1 >> 16) - (rep2 >> 16);
  231.  
  232.     if (repr < -32768 || repr > 32767)
  233.         FixedError(f1, f2, "Sub oflw");
  234.  
  235.     return FW_ODFixedToFixed(f1.fRep - f2.fRep);
  236. }
  237.  
  238. FW_Wide& operator += (FW_Wide& w1, const FW_Fixed& f2)
  239. {
  240.     FW_Wide w2 = FW_FixedToWide(f2);
  241.     return w1 += w2;
  242. }
  243.  
  244. FW_Wide& operator -= (FW_Wide& w1, const FW_Fixed& f2)
  245. {
  246.     FW_Wide w2 = FW_FixedToWide(f2);
  247.     return w1 -= w2;
  248. }
  249.  
  250. FW_Fixed operator*(FW_Fixed f1, FW_Fixed f2)
  251. {
  252.     long rep1 = f1.fRep;
  253.     long rep2 = f2.fRep;
  254.  
  255.     long repr  = (rep1 >> 16) * (rep2 >> 16);
  256.     
  257.     if (repr < -32768 || repr > 32767)
  258.         FixedError(f1, f2, "Mul oflw");
  259.  
  260.     return FW_ODFixedToFixed(ODFixedMultiply(f1.fRep, f2.fRep));
  261. }
  262.  
  263. FW_Fixed operator/(FW_Fixed f1, FW_Fixed f2)
  264. {
  265.     if (f2.fRep == 0)
  266.         FixedError(f1, f2, "Div by 0");
  267.  
  268.     return FW_ODFixedToFixed(ODFixedDivide(f1.fRep, f2.fRep));
  269. }
  270.  
  271. #endif
  272.  
  273. #include <math.h>
  274.  
  275. // #ifdef FW_BUILD_WIN
  276. // [KVV] OpenDoc DR2 for Windows is missing the following routines
  277.  
  278. #if defined(FW_BUILD_WIN) || (defined(__MWERKS__) && GENERATING68K)
  279. // [JEL] And we need ODFractSinCos for Metrowerks CFM68K too
  280. ODFract    ODFractSinCos(ODFixed angle, ODFract *cosResult)
  281. {
  282.     double flAngle    = ODFixedToFloat(angle);
  283.  
  284.     double flSin    = sin(flAngle);
  285.     double flCos    = cos(flAngle);
  286.     
  287.     ODFixed fxSin    = ODFloatToFixed(flSin);
  288.     ODFixed fxCos    = ODFloatToFixed(flCos);
  289.     
  290.     if(cosResult != NULL)
  291.         *cosResult = ODFixedToFract(fxCos);
  292.         
  293.     return ODFixedToFract(fxSin);
  294. }
  295. #endif
  296.  
  297. #ifdef FW_BUILD_WIN
  298.  
  299. ODULong ODWideSquareRoot(const ODWide *src)
  300. {
  301.     if(src->hi == 0 && src->lo == 0)
  302.         return 0;
  303.  
  304.     if(src->hi < 0)
  305.         return 0x7FFFFFFFl;
  306.         
  307.     double d = src->hi + src->lo / 4294967296.0;
  308.     double s = sqrt(d);
  309.     
  310.     return ODFloatToFixed(s);
  311. }
  312.  
  313. #endif
  314.